//
// ba_gpb_syntcpserv.cpp

#include <iostream>
#include <string>

#include <boost/asio.hpp>

#include "hiout.pb.h"

#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>

using boost::asio::ip::tcp;

using namespace google::protobuf::io;

const int portnum = 24312; //randomly chosen


// This function fills in a Person message based on user input.
void promptForData(hi::TrackData& trackData) {
	using namespace std;
	cout << "Enter active: ";
	bool active;
	cin >> active;
	trackData.set_active(active);
	cin.ignore(256, '\n');
	
	cout << "Enter x: ";
	int x;
	cin >> x;
	trackData.set_x(x);
	cin.ignore(256, '\n');
	
	cout << "Enter y: ";
	int y;
	cin >> y;
	trackData.set_y(y);
	cin.ignore(256, '\n');	
}

void writeTrackDataToArray( hi::TrackData& trackData, char* dataBuf, int dataBufSize ) {

	ZeroCopyOutputStream* rawOutputPtr = new ArrayOutputStream( dataBuf, dataBufSize );
	CodedOutputStream* codedOutputPtr = new CodedOutputStream(rawOutputPtr); 
	
	codedOutputPtr->WriteVarint32( trackData.ByteSize() );
	trackData.SerializeToCodedStream( codedOutputPtr );
	
	delete codedOutputPtr;
	delete rawOutputPtr;
}

int main()
{
	
	// Verify that the version of the library that we linked against is
	// compatible with the version of the headers we compiled against.
	GOOGLE_PROTOBUF_VERIFY_VERSION;
	
	try
	{
		boost::asio::io_service io_service;
		
		tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), portnum));
		
		for (;;)
		{
			tcp::socket socket(io_service);
			acceptor.accept(socket);
			
			
			// Make msg! 
			hi::TrackData trackData;
			
			// Get data
			promptForData( trackData );
			
			int dataBufSize = trackData.ByteSize()+4;//FIXNOW specify integer size in a proper manner!
			
			char trackDataBuf[dataBufSize]; 
			
			writeTrackDataToArray( trackData, trackDataBuf, dataBufSize );
			
			boost::system::error_code ignored_error;
			boost::asio::write(socket, boost::asio::buffer(trackDataBuf,dataBufSize),
							   boost::asio::transfer_all(), ignored_error);
		}
	}
	catch (std::exception& e)
	{
		std::cerr << e.what() << std::endl;
	}
	
	
	// Optional:  Delete all global objects allocated by libprotobuf.
	google::protobuf::ShutdownProtobufLibrary();
	
	return 0;
}